{
  "cells": [
    {
      "cell_type": "raw",
      "id": "afaf8039",
      "metadata": {
        "vscode": {
          "languageId": "raw"
        }
      },
      "source": [
        "---\n",
        "sidebar_label: MistralAI\n",
        "---"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e49f1e0d",
      "metadata": {},
      "source": [
        "# ChatMistralAI\n",
        "\n",
        "[Mistral AI](https://mistral.ai/) is a platform that offers hosting for their powerful [open source models](https://docs.mistral.ai/getting-started/models/).\n",
        "\n",
        "This will help you getting started with ChatMistralAI [chat models](/docs/concepts/chat_models). For detailed documentation of all ChatMistralAI features and configurations head to the [API reference](https://api.js.langchain.com/classes/langchain_mistralai.ChatMistralAI.html).\n",
        "\n",
        "## Overview\n",
        "### Integration details\n",
        "\n",
        "| Class | Package | Local | Serializable | [PY support](https://python.langchain.com/docs/integrations/chat/mistralai) | Package downloads | Package latest |\n",
        "| :--- | :--- | :---: | :---: |  :---: | :---: | :---: |\n",
        "| [ChatMistralAI](https://api.js.langchain.com/classes/langchain_mistralai.ChatMistralAI.html) | [`@langchain/mistralai`](https://www.npmjs.com/package/@langchain/mistralai) | ❌ | ❌ | ✅ | ![NPM - Downloads](https://img.shields.io/npm/dm/@langchain/mistralai?style=flat-square&label=%20&) | ![NPM - Version](https://img.shields.io/npm/v/@langchain/mistralai?style=flat-square&label=%20&) |\n",
        "\n",
        "### Model features\n",
        "\n",
        "See the links in the table headers below for guides on how to use specific features.\n",
        "\n",
        "| [Tool calling](/docs/how_to/tool_calling) | [Structured output](/docs/how_to/structured_output/) | JSON mode | [Image input](/docs/how_to/multimodal_inputs/) | Audio input | Video input | [Token-level streaming](/docs/how_to/chat_streaming/) | [Token usage](/docs/how_to/chat_token_usage_tracking/) | [Logprobs](/docs/how_to/logprobs/) |\n",
        "| :---: | :---: | :---: | :---: |  :---: | :---: | :---: | :---: | :---: |\n",
        "| ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | \n",
        "\n",
        "## Setup\n",
        "\n",
        "To access Mistral AI models you'll need to create a Mistral AI account, get an API key, and install the `@langchain/mistralai` integration package.\n",
        "\n",
        "### Credentials\n",
        "\n",
        "Head [here](https://console.mistral.ai/) to sign up to Mistral AI and generate an API key. Once you've done this set the `MISTRAL_API_KEY` environment variable:\n",
        "\n",
        "```bash\n",
        "export MISTRAL_API_KEY=\"your-api-key\"\n",
        "```\n",
        "\n",
        "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:\n",
        "\n",
        "```bash\n",
        "# export LANGSMITH_TRACING=\"true\"\n",
        "# export LANGSMITH_API_KEY=\"your-api-key\"\n",
        "```\n",
        "\n",
        "### Installation\n",
        "\n",
        "The LangChain ChatMistralAI integration lives in the `@langchain/mistralai` package:\n",
        "\n",
        "```{=mdx}\n",
        "import IntegrationInstallTooltip from \"@mdx_components/integration_install_tooltip.mdx\";\n",
        "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
        "\n",
        "<IntegrationInstallTooltip></IntegrationInstallTooltip>\n",
        "\n",
        "<Npm2Yarn>\n",
        "@langchain/mistralai @langchain/core\n",
        "</Npm2Yarn>\n",
        "\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a38cde65-254d-4219-a441-068766c0d4b5",
      "metadata": {},
      "source": [
        "## Instantiation\n",
        "\n",
        "Now we can instantiate our model object and generate chat completions:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cb09c344-1836-4e0c-acf8-11d13ac1dbae",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { ChatMistralAI } from \"@langchain/mistralai\" \n",
        "\n",
        "const llm = new ChatMistralAI({\n",
        "    model: \"mistral-large-latest\",\n",
        "    temperature: 0,\n",
        "    maxRetries: 2,\n",
        "    // other params...\n",
        "})"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2b4f3e15",
      "metadata": {},
      "source": [
        "## Invocation\n",
        "\n",
        "When sending chat messages to mistral, there are a few requirements to follow:\n",
        "\n",
        "- The first message can _*not*_ be an assistant (ai) message.\n",
        "- Messages _*must*_ alternate between user and assistant (ai) messages.\n",
        "- Messages can _*not*_ end with an assistant (ai) or system message."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "62e0dbc3",
      "metadata": {
        "tags": []
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"content\": \"J'adore la programmation.\",\n",
            "  \"additional_kwargs\": {},\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completionTokens\": 9,\n",
            "      \"promptTokens\": 27,\n",
            "      \"totalTokens\": 36\n",
            "    },\n",
            "    \"finish_reason\": \"stop\"\n",
            "  },\n",
            "  \"tool_calls\": [],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 27,\n",
            "    \"output_tokens\": 9,\n",
            "    \"total_tokens\": 36\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "const aiMsg = await llm.invoke([\n",
        "    [\n",
        "        \"system\",\n",
        "        \"You are a helpful assistant that translates English to French. Translate the user sentence.\",\n",
        "    ],\n",
        "    [\"human\", \"I love programming.\"],\n",
        "])\n",
        "aiMsg"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "d86145b3-bfef-46e8-b227-4dda5c9c2705",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "J'adore la programmation.\n"
          ]
        }
      ],
      "source": [
        "console.log(aiMsg.content)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "18e2bfc0-7e78-4528-a73f-499ac150dca8",
      "metadata": {},
      "source": [
        "## Chaining\n",
        "\n",
        "We can [chain](/docs/how_to/sequence/) our model with a prompt template like so:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "e197d1d7-a070-4c96-9f8a-a0e86d046e0b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "AIMessage {\n",
            "  \"content\": \"Ich liebe Programmieren.\",\n",
            "  \"additional_kwargs\": {},\n",
            "  \"response_metadata\": {\n",
            "    \"tokenUsage\": {\n",
            "      \"completionTokens\": 7,\n",
            "      \"promptTokens\": 21,\n",
            "      \"totalTokens\": 28\n",
            "    },\n",
            "    \"finish_reason\": \"stop\"\n",
            "  },\n",
            "  \"tool_calls\": [],\n",
            "  \"invalid_tool_calls\": [],\n",
            "  \"usage_metadata\": {\n",
            "    \"input_tokens\": 21,\n",
            "    \"output_tokens\": 7,\n",
            "    \"total_tokens\": 28\n",
            "  }\n",
            "}\n"
          ]
        }
      ],
      "source": [
        "import { ChatPromptTemplate } from \"@langchain/core/prompts\"\n",
        "\n",
        "const prompt = ChatPromptTemplate.fromMessages(\n",
        "    [\n",
        "        [\n",
        "            \"system\",\n",
        "            \"You are a helpful assistant that translates {input_language} to {output_language}.\",\n",
        "        ],\n",
        "        [\"human\", \"{input}\"],\n",
        "    ]\n",
        ")\n",
        "\n",
        "const chain = prompt.pipe(llm);\n",
        "await chain.invoke(\n",
        "    {\n",
        "        input_language: \"English\",\n",
        "        output_language: \"German\",\n",
        "        input: \"I love programming.\",\n",
        "    }\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d1ee55bc-ffc8-4cfa-801c-993953a08cfd",
      "metadata": {},
      "source": [
        "## Tool calling\n",
        "\n",
        "Mistral's API supports [tool calling](/docs/concepts/tool_calling) for a subset of their models. You can see which models support tool calling [on this page](https://docs.mistral.ai/capabilities/function_calling/).\n",
        "\n",
        "The examples below demonstrates how to use it:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "98d9034c",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[\n",
            "  {\n",
            "    name: 'calculator',\n",
            "    args: { operation: 'add', number1: 2, number2: 2 },\n",
            "    type: 'tool_call',\n",
            "    id: 'DD9diCL1W'\n",
            "  }\n",
            "]\n"
          ]
        }
      ],
      "source": [
        "import { ChatMistralAI } from \"@langchain/mistralai\";\n",
        "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
        "import { z } from \"zod\";\n",
        "import { tool } from \"@langchain/core/tools\";\n",
        "\n",
        "const calculatorSchema = z.object({\n",
        "  operation: z\n",
        "    .enum([\"add\", \"subtract\", \"multiply\", \"divide\"])\n",
        "    .describe(\"The type of operation to execute.\"),\n",
        "  number1: z.number().describe(\"The first number to operate on.\"),\n",
        "  number2: z.number().describe(\"The second number to operate on.\"),\n",
        "});\n",
        "\n",
        "const calculatorTool = tool((input) => {\n",
        "  return JSON.stringify(input);\n",
        "}, {\n",
        "  name: \"calculator\",\n",
        "  description: \"A simple calculator tool\",\n",
        "  schema: calculatorSchema,\n",
        "});\n",
        "\n",
        "// Bind the tool to the model\n",
        "const modelWithTool = new ChatMistralAI({\n",
        "  model: \"mistral-large-latest\",\n",
        "}).bindTools([calculatorTool]);\n",
        "\n",
        "\n",
        "const calcToolPrompt = ChatPromptTemplate.fromMessages([\n",
        "  [\n",
        "    \"system\",\n",
        "    \"You are a helpful assistant who always needs to use a calculator.\",\n",
        "  ],\n",
        "  [\"human\", \"{input}\"],\n",
        "]);\n",
        "\n",
        "// Chain your prompt, model, and output parser together\n",
        "const chainWithCalcTool = calcToolPrompt.pipe(modelWithTool);\n",
        "\n",
        "const calcToolRes = await chainWithCalcTool.invoke({\n",
        "  input: \"What is 2 + 2?\",\n",
        "});\n",
        "console.log(calcToolRes.tool_calls);"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "85dcbecc",
      "metadata": {},
      "source": [
        "## Hooks\n",
        "\n",
        "Mistral AI supports custom hooks for three events: beforeRequest, requestError, and reponse. Examples of the function signature for each hook type can be seen below:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "74b8b855",
      "metadata": {},
      "outputs": [],
      "source": [
        "const beforeRequestHook = (req: Request): Request | void | Promise<Request | void> => {\n",
        "    // Code to run before a request is processed by Mistral\n",
        "};\n",
        "\n",
        "const requestErrorHook = (err: unknown, req: Request): void | Promise<void> => {\n",
        "    // Code to run when an error occurs as Mistral is processing a request\n",
        "};\n",
        "\n",
        "const responseHook = (res: Response, req: Request): void | Promise<void> => {\n",
        "    // Code to run before Mistral sends a successful response\n",
        "};"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "930df6c4",
      "metadata": {},
      "source": [
        "To add these hooks to the chat model, either pass them as arguments and they are automatically added:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8b8084f6",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { ChatMistralAI } from \"@langchain/mistralai\" \n",
        "\n",
        "const modelWithHooks = new ChatMistralAI({\n",
        "    model: \"mistral-large-latest\",\n",
        "    temperature: 0,\n",
        "    maxRetries: 2,\n",
        "    beforeRequestHooks: [ beforeRequestHook ],\n",
        "    requestErrorHooks: [ requestErrorHook ],\n",
        "    responseHooks: [ responseHook ],\n",
        "    // other params...\n",
        "});"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cc9478f3",
      "metadata": {},
      "source": [
        "Or assign and add them manually after instantiation:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "daa70dc3",
      "metadata": {},
      "outputs": [],
      "source": [
        "import { ChatMistralAI } from \"@langchain/mistralai\" \n",
        "\n",
        "const model = new ChatMistralAI({\n",
        "    model: \"mistral-large-latest\",\n",
        "    temperature: 0,\n",
        "    maxRetries: 2,\n",
        "    // other params...\n",
        "});\n",
        "\n",
        "model.beforeRequestHooks = [ ...model.beforeRequestHooks, beforeRequestHook ];\n",
        "model.requestErrorHooks = [ ...model.requestErrorHooks, requestErrorHook ];\n",
        "model.responseHooks = [ ...model.responseHooks, responseHook ];\n",
        "\n",
        "model.addAllHooksToHttpClient();"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "389f5159",
      "metadata": {},
      "source": [
        "The method addAllHooksToHttpClient clears all currently added hooks before assigning the entire updated hook lists to avoid hook duplication.\n",
        "\n",
        "Hooks can be removed one at a time, or all hooks can be cleared from the model at once."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a56b64bb",
      "metadata": {},
      "outputs": [],
      "source": [
        "model.removeHookFromHttpClient(beforeRequestHook);\n",
        "\n",
        "model.removeAllHooksFromHttpClient();"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
      "metadata": {},
      "source": [
        "## API reference\n",
        "\n",
        "For detailed documentation of all ChatMistralAI features and configurations head to the API reference: https://api.js.langchain.com/classes/langchain_mistralai.ChatMistralAI.html"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "TypeScript",
      "language": "typescript",
      "name": "tslab"
    },
    "language_info": {
      "codemirror_mode": {
        "mode": "typescript",
        "name": "javascript",
        "typescript": true
      },
      "file_extension": ".ts",
      "mimetype": "text/typescript",
      "name": "typescript",
      "version": "3.7.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}
